home *** CD-ROM | disk | FTP | other *** search
- /*
- Program : Coil v2.0
- Purpose : Create coil objects for PoV Ray v1.0 raytracer
- Created : 7/25/92
- By : Bill Kirby CIS [70711,2407]
- File : COIL.C
- Compiler: Borland C++ v3.1
- Model : Small
- Comments: Creates twisted coil object made with spheres.
- */
- /*
- Program : Coil v2.10b
- Purpose : Create coil objects for PoV Ray v1.0 and Polyray v1.6 raytracers
- and also export to CTDS and WORM file formats.
- Created : 9/14/93
- By : Rob Bryerton CIS [73747,433]... based on original C code
- by Bill Kirby
- File : COIL.CPP
- Compiler: Microsoft C++ v8.00
- Model : Small
- Comments: Creates twisted coil object made with spheres or other shapes
- */
-
- #include <fstream.h>
- #include <math.h>
- #include <stdio.h> // for getchar()
- #include <stdlib.h>
- #include <string.h>
- #include <graph.h> // for graphics
-
- ofstream outfile;
- const int BUFFSIZE = 256;
- enum Format {POV,POLY,CTDS,WORM};
- enum bool {FALSE,TRUE};
- enum Shape {Sphere,Ellipsoid,Box,Cone,Y_Cylinder};
- char buff[BUFFSIZE];
- const double PI = 3.1415926535897932384626;
-
- /*
- #ifndef PI
- #define PI 3.1415926535897932384626
- #endif*/
-
-
- void err_exit(char *message);
- void usage(void);
-
- class Base_Obj
- {
- protected:
- double x_1,y_1,x_2,z_2,xpos,ypos,zpos,Rad1,rad2,radius,angle1,angle2,k;
- double xpos_1,ypos_1; // for graphics... remembers 1st graphics points
- long Ntwist,Ntube,counter,steps,shape_type;
- char com[3],union_name[80];
- bool extended, display;
- Format format;
- Shape shape;
- int v_mode;
- public:
- char filename[80];
- Base_Obj(){ // no arg constructor
- xpos=0.0; ypos=0.0; zpos=0.0; radius=0.25;strcpy(com,"//");
- extended=FALSE;display = FALSE; format=POV; counter=0;shape=Sphere;
- outfile.setf(ios::showpoint | ios::fixed);outfile.precision(6); }
- virtual void do_calc(void);
- virtual void get_inputs(void);
- void init_display(void);
- void close_display(void);
- void draw_piece(void);
- void process_args(int argc, char* argv[]);
- void process_option(char *s);
- void set_precision(char *prec);
- void show_title(void);
- virtual void write_end(void){};
- virtual void write_header(void);
- virtual bool write_piece(void){if(display) draw_piece(); // draw current line
- return (counter < steps) ? TRUE:FALSE; }
- };
-
- class POV_Obj:public Base_Obj
- {
- private:
- double xmax,xmin,ymax,ymin,zmax,zmin;
- public:
- POV_Obj(){
- xmax=0.0,xmin=0.0,ymax=0.0, // no arg constructor
- ymin=0.0,zmax=0.0,zmin=0.0;}
- void do_calc(void);
- void get_inputs(void);
- void write_header(void);
- bool write_piece(void);
- void write_end(void);
- };
-
- class POLY_Obj:public Base_Obj
- {
- public:
- POLY_Obj(){format=POLY;}
- void get_inputs(void);
- void write_header(void);
- bool write_piece(void);
- void write_end(void);
- };
-
- class CTDS_Obj:public Base_Obj // ********** full definition of class
- {
- public:
- CTDS_Obj() {format=CTDS; strcpy(com,";"); strcpy(union_name,"-----");}
- bool write_piece(void)
- {
- outfile << xpos << " " << ypos << " " << zpos << " "
- << radius << endl;
- Base_Obj::write_piece();
- return ((counter < steps) ? TRUE:FALSE);
- }
- void write_end(void){};
- };
-
- class WORM_Obj:public Base_Obj // ********** full definition of class
- {
- public:
- WORM_Obj(){format=WORM;}
- void write_header(void)
- { outfile << steps << endl; }
- bool write_piece(void)
- {
- outfile << xpos << ", " << ypos << ", " << zpos << ", "
- << radius <<", " << (counter==1?0:1) << endl;
- Base_Obj::write_piece();
- return ((counter < steps) ? TRUE:FALSE);}
- void write_end(void){};
- };
-
-
-
- //main
- int main(int argc, char* argv[])
- {
- int choice = 1;
-
- Base_Obj* coil_ptr; // pointer to class Base_Obj
- Base_Obj vec; // object of " " " "
- coil_ptr = &vec;
-
- if(argc > 1) coil_ptr->process_args (argc, argv); // check for validity
-
- coil_ptr->show_title();
-
- cout<< "1\tPOV\n2\tPolyray\n3\tCTDS\n4\tWORM\n" << "Number for format? [1]: ";
- cin.getline(buff,BUFFSIZE); choice = atoi(buff); // output format
-
- switch(choice){ // construct appropriate object based on above choice
- case 2: {POLY_Obj vec2; coil_ptr = &vec2;} break;
- case 3: {CTDS_Obj vec3; coil_ptr = &vec3;} break;
- case 4: {WORM_Obj vec4; coil_ptr = &vec4;} break;
- default:{POV_Obj vec1; coil_ptr = &vec1;} }
-
- if(argc > 1) coil_ptr->process_args (argc, argv); // set options
-
- coil_ptr->get_inputs(); // get parameters from user
-
- outfile.open(coil_ptr->filename,ios::out); // try to open disk file
- if(! outfile) err_exit("Opening file."); // if disk access error,exit
-
- coil_ptr->write_header(); // success, make a coil
-
- coil_ptr->init_display(); // set up display if desired
- cerr<< "\nCreating data file " << coil_ptr->filename << endl;
-
- do coil_ptr->do_calc(); // calculate current vector
- while(coil_ptr->write_piece()); // write current line to disk
-
- coil_ptr->write_end(); // write texture block (POV or Polyray only)
- outfile.close; // close disk file
-
- coil_ptr->close_display(); // exit graphics mode if applicable
- cout << "\nFile " << coil_ptr->filename <<" created.\n";
-
- return(0);
- }
-
-
-
- void err_exit(char *message)
- {
- cerr << "\n\nERROR! \a" << message << "... Exiting \n";
- exit(1);
- }
-
-
- void usage()
- {
- cerr << "\n--------------------------------Coil v2.10--------------------------------------"
- << "Usage: coil [options]\n"
- << "Options: -d# enables 2D (xy) display of coil... # is the graphics mode\n"
- << " 1=640x480 2=800x600 3=1024x768 (default # value is 1)\n\n"
- << " -e gives you an extended menu with a choice of objects \n"
- << " (cone, cylinder, box, etc.) for POV-Ray or Polyray output.\n\n"
- << " -p# where # is the precision of the output file numbers.\n"
- << " Range is 2 - 9 with a default precision of 6 decimal places.\n"
- << "\nType COIL with no parameters for the default menus and options.\n"
- << "--------------------------------------------------------------------------------";
- }
-
-
-
- // ************* Base and Derived Class function definitions**************
-
-
- // ************* Base Class Base_Obj function definitions **************
-
- void Base_Obj::close_display()
- {
- if(display){
- cerr << "\nPress return.";
- getchar();
- _setvideomode(_DEFAULTMODE);}
- }
-
- void Base_Obj::do_calc()
- {
- angle1 = 2 * PI * Ntube * (double)counter / (double)steps;
- x_1 = cos( angle1 );y_1 = sin( angle1 );
- angle2 = (double)( Ntwist + 1.0/Ntube) * angle1;
- x_2 = cos( angle2 );z_2 = sin( angle2);
- xpos = k * ((Rad1 * x_1) + (rad2 * x_2 * x_1));
- ypos = k * ((Rad1 * y_1) + (rad2 * x_2 * y_1));
- zpos = k * rad2 * z_2; counter++;
- }
-
- void Base_Obj::draw_piece()
- {
- struct _videoconfig vc;
- _getvideoconfig( &vc );
- _setcolor (12); /* brt red */
- double rads = Rad1+rad2;
- int vidx = int((xpos*(vc.numxpixels*0.33)/k)/rads+(0.5*vc.numxpixels));
- int vidy = int((ypos*(vc.numxpixels*0.33)/k)/rads+(0.5*vc.numypixels));
- if(counter==1){ _moveto (vidx, vidy); xpos_1=vidx; ypos_1=vidy; }
- if(counter<=steps){ _lineto (vidx,vidy); _setcolor (10); /* brt grn */
- int elip_x1 = (vidx-(radius*(0.28*vc.numypixels/k)));
- int elip_y1 = (vidy-(radius*(0.28*vc.numypixels/k)));
- int elip_x2 = (vidx+(radius*(0.28*vc.numypixels/k)));
- int elip_y2 = (vidy+(radius*(0.28*vc.numypixels/k)));
- //_ellipse( _GBORDER, vidx-(radius*(0.28*vc.numxpixels)),vidy-(radius*(0.28*vc.numxpixels)),vidx+(radius*(0.28*vc.numxpixels)),vidy+(radius*(0.28*vc.numxpixels))); }
- _ellipse( _GBORDER, elip_x1, elip_y1, elip_x2, elip_y2); }
- if(counter==steps){ _setcolor (12); _lineto (xpos_1,ypos_1); }
- }
-
-
-
- void Base_Obj::get_inputs()
- {
- cout << "Ouput filename? [coil.inc]: ";
- cin.getline(buff,BUFFSIZE); strcpy(filename,buff);
-
- if(format < CTDS){
- cout << "Union name? [coil]: ";
- cin.getline(buff,BUFFSIZE); strcpy(union_name,buff);}
-
- cout << "Number of objects? [100]: ";
- cin.getline(buff,BUFFSIZE); steps = atoi(buff);
-
- cout << "Number of objects in cross-section? [2]: ";
- cin.getline(buff,BUFFSIZE); Ntube = atoi(buff);
-
- cout << "Number of twists per revolution? [2]: ";
- cin.getline(buff,BUFFSIZE); Ntwist = atoi(buff);
-
- cout << "Major radius? [1.0]: ";
- cin.getline(buff,BUFFSIZE); Rad1 = atof(buff);
-
- cout << "Minor radius? [0.25]: ";
- cin.getline(buff,BUFFSIZE); rad2 = atof(buff);
-
- cout << "Object 'radius'? [0.25]: ";
- cin.getline(buff,BUFFSIZE); radius = atof(buff);
-
- cout << "Overall scale value (k)? [1.0]: ";
- cin.getline(buff,BUFFSIZE); k = atof(buff);
-
- // Set up default values
- if(filename[0]=='\0') strcpy(filename,"coil.inc");
- if(union_name[0]=='\0') strcpy(union_name,"coil");
- if(steps==0) steps = 100; if(Ntube==0) Ntube = 2;
- if(Ntwist==0) Ntwist = 2; if(Rad1==0.0) Rad1 = 1.0;
- if(rad2==0.0) rad2 = 0.25; if(radius==0.0) radius = 0.25;
- if(k==0.0) k = 1.0; if(shape_type==0) shape_type = 1;
- switch(shape_type){
- case 2 : shape = Ellipsoid; break;
- case 3 : shape = Box; break;
- case 4 : shape = Cone; break;
- case 5 : shape = Y_Cylinder; break;
- default: shape = Sphere;
- }
- }
-
- void Base_Obj::init_display()
- { if(display){
- switch(v_mode){
- case 3 : if(!_setvideomode(_XRES16COLOR)) cerr << "\nCouldn't set graphics mode... continuing\n";
- break; /* 1024x768x16 */
- case 2 : if(!_setvideomode(_SRES16COLOR)) cerr << "\nCouldn't set graphics mode... continuing\n";
- break; /* 800x600x16 */
- default : if(!_setvideomode(_VRES16COLOR)) cerr << "\nCouldn't set graphics mode... continuing\n";
- } /* 640x480x16 */
- }
- }
-
- void Base_Obj::process_args (int argc, char* argv[])
- {
- for (int i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-' || argv[i][0] == '/')
- process_option (&argv[i][1]);
- else
- {usage(); err_exit("Invalid option");}
- }
- }
-
-
- void Base_Obj::process_option (char *s)
- {
- switch (toupper(s[0]))
- {
- case 'E': extended = TRUE; break;
- case 'P': set_precision(&s[1]); break;
- case 'D': display = TRUE; v_mode = atoi(&s[1]); break;
- case '?': usage(); exit(0);
- case 'H': usage(); exit(0);
- default : usage(); err_exit("Invalid option");
- }
- }
-
-
- void Base_Obj::set_precision(char *prec)
- {
- outfile.precision((atoi(prec) > 1 ? atoi(prec) : 6 ));
- }
-
-
- void Base_Obj::show_title()
- {
- cout << "Coil v2.10\n"
- << "Creates a data file of a twisted coil object for the PoV-Ray v1.0" << endl
- << "and Polyray v1.6 raytracers, Connect The Dots Smoother (CTDS), and WORM.\n"
- << "- v2.0 C source by W. D. Kirby 7/25/92\n"
- << "- v2.1 C++ update by R. Bryerton 9/14/93\n\n";
- }
-
-
-
- void Base_Obj::write_header()
- {
- outfile
- <<com<<" File: "<<filename<<" Union Name: "<<union_name<< endl
- <<com<<" This data file created by COIL.EXE v2.10 for the PoV Ray v1.0 and\n"
- <<com<<" Polyray v1.6 raytracers, Connect The Dots Smoother (CTDS), and WORM.\n\n"
- <<com<<" Twists="<<Ntwist<<" Cross Section="<<Ntube<<" Objects="<<steps<<" Scale=" << k << "\n\n";
- }
-
-
- // *************************** Derived Class POV_Obj function definitions
- void POV_Obj::get_inputs()
- {
- if(extended){
- cout << "\n1\tSphere\n2\tEllipsoid\n3\tBox\n4\tCone\n5\tY_Cylinder\n";
- cout << "Shape type? [1]: ";
- cin.getline(buff,BUFFSIZE); shape_type = atoi(buff); }
-
- Base_Obj::get_inputs(); // call base class function
- }
-
- void POV_Obj::do_calc()
- {
- Base_Obj::do_calc(); //call base class function 1st
- xmax = __max(xmax,xpos);xmin = __min(xmin,xpos); // calculate bounds
- ymax = __max(ymax,ypos);ymin = __min(ymin,ypos); // (POV only)
- zmax = __max(zmax,zpos);zmin = __min(zmin,zpos);
- }
-
- void POV_Obj::write_header()
- {
- Base_Obj::write_header(); // call base class function first
-
- if(shape > Sphere){
- outfile << "// You MUST #declare shapes.inc in either this file or your .POV file...\n\n"
- << "#declare object_scale = <" << 0.5*radius << " "<< 0.5*radius << " "<< 0.5*radius << ">"<< endl
- << "#declare object_rotate = <0 0 0>" << endl
- << "// Change object_scale and object_rotate to modify EVERY object\n\n";
- }
-
- outfile << "declare "<<union_name<<" = object {\n union {\n";
-
- }
-
-
- bool POV_Obj::write_piece()
- {
- switch(shape){
- case Ellipsoid : outfile << " quadric { Ellipsoid scale object_scale rotate object_rotate translate< "<<xpos<<" "<<ypos<<" "<<zpos<<" > } \n"; break;
- case Box : outfile << " box { UnitBox scale object_scale rotate object_rotate translate< "<<xpos<<" "<<ypos<<" "<<zpos<<" > } \n"; break;
- case Cone : outfile << " intersection { Cone_Y scale object_scale rotate object_rotate translate< "<<xpos<<" "<<ypos<<" "<<zpos<<" > } \n"; break;
- case Y_Cylinder : outfile << " intersection { Disk_Y scale object_scale rotate object_rotate translate< "<<xpos<<" "<<ypos<<" "<<zpos<<" > } \n"; break;
- default : outfile << " sphere { < "<<xpos<<" "<<ypos<<" "<<zpos<<" > "<<radius<<" }\n";}
- Base_Obj::write_piece(); return (counter < steps) ? TRUE:FALSE;
- }
-
- void POV_Obj::write_end()
- { // calculate bounding box
- xmax = 1.01 * (xmax + radius); xmin = 1.01 * (xmin - radius);
- ymax = 1.01 * (ymax + radius); ymin = 1.01 * (ymin - radius);
- zmax = 1.01 * (zmax + radius); zmin = 1.01 * (zmin - radius);
- outfile << " }\n\n"
- << "bounded_by {\n"
- << " box { < " << xmin<<" "<<ymin<<" "<<zmin << "> < "
- << xmax<<" "<<ymax<<" "<<zmax << "> }\n }\n"
- << " texture {\n"
- << " ambient 0.3\n"
- << " diffuse 0.7\n"
- << " phong 1.0\n"
- << " phong_size 20.0\n"
- << " color red 1.0 green 0.0 blue 0.0\n"
- << " }\n\n}\n\n";
-
- }
-
- // *************************** Derived Class POLY_Obj function definitions
- void POLY_Obj::get_inputs()
- {
- if(extended){
- cout << "\n1\tSphere\n2\tEllipsoid\n3\tBox\n4\tCone\n5\tY_Cylinder\n\n";
- cout << "Shape type? [1]: ";
- cin.getline(buff,BUFFSIZE); shape_type = atoi(buff);}
-
- Base_Obj::get_inputs(); // call base class function
- }
-
- void POLY_Obj::write_header()
- {
- Base_Obj::write_header(); // call base class function first
-
- if(shape > Sphere) outfile << "define object_scale <" << 0.5*radius << ", " << 0.5*radius << ", " << 0.5*radius << ">\n"
- << "define object_rotate <0, 0, 0>\n"
- <<"// Change object_scale and object_rotate to modify EVERY object\n\n";
-
- switch(shape){ // cap the cone and cylinder to be consistent w/POV
- case Ellipsoid : outfile << "define Ellipsoid object{ sphere<0,0,0>,1 scale object_scale rotate object_rotate}\n"; break;
- case Box : outfile << "define UnitBox object{ box<-1,-1,-1>,<1,1,1> scale object_scale rotate object_rotate}\n";break;
- case Cone : outfile << "define Y_Cone object{\n object{cone<0,-1,0>,1,<0,1,0>,0 scale object_scale rotate object_rotate}+\n"
- << " object {disc <0, -1, 0>, <0, 1, 0>, 1 scale object_scale rotate object_rotate}\n}\n";break;
- case Y_Cylinder: outfile << "define Y_Cylinder object{\n object{cylinder<0,-1,0>,<0,1,0>,1 scale object_scale rotate object_rotate}+\n"
- << " object {disc <0, 1, 0>, <0, 1, 0>, 1 scale object_scale rotate object_rotate}+\n"
- << " object {disc <0, -1, 0>, <0, 1, 0>, 1 scale object_scale rotate object_rotate}\n}\n";break;
- default : break; }
- outfile << "\ndefine "<<union_name<<"\n object {\n";
- }
-
- bool POLY_Obj::write_piece()
- {
- switch(shape){
- case Ellipsoid : outfile << " Ellipsoid{ translate<" << xpos << ", " << ypos << ", " << zpos << ">} "; break;
- case Box : outfile << " UnitBox{ translate<" << xpos << ", " << ypos << ", " << zpos << ">} "; break;
- case Cone : outfile << " Y_Cone{ translate<" << xpos << ", " << ypos << ", " << zpos << ">} "; break;
- case Y_Cylinder: outfile << " Y_Cylinder{ translate<" << xpos << ", " << ypos << ", " << zpos << ">} "; break;
- default : outfile << " object { sphere < "<<xpos<<", "<<ypos<<", "<<zpos<<" >, "<<radius<<" } ";}
-
- if (counter < steps) // for all obects EXCEPT the last
- outfile << "+\n";
- else // for last object only (no "+")
- outfile << endl;
-
- Base_Obj::write_piece(); return (counter < steps) ? TRUE:FALSE;
- }
-
- void POLY_Obj::write_end()
- {
- outfile << " texture {\n"
- << " surface {\n"
- << " ambient red, 0.275\n"
- << " diffuse red, 0.8\n"
- << " specular white, 1.0\n"
- << " microfacet Phong 7\n }\n"
- << " }\n\n}\n\n";
-
- }
-
-